home *** CD-ROM | disk | FTP | other *** search
/ Over 1,000 Windows 95 Programs / Over 1000 Windows 95 Programs (Microforum) (Disc 1).iso / 0620 / talk.txt < prev    next >
Text File  |  1997-04-06  |  14KB  |  425 lines

  1.                         Talkline - How it works.
  2.                         ~~~~~~~~~~~~~~~~~~~~~~~~
  3.  
  4.      Talkline is a sound of short duration, appended to the end of a message.
  5.      In this fist version, up to 5 seconds of sound can be added.
  6.      The purpose of this text file is to explain how the sound is coded
  7. and appended to the message.   This first version is called version "A" and
  8. has the following characterization:
  9.  
  10. 1-Sampling. - The sound bandwidth supports human voice only and so is sampled
  11.    at 5012.5Hz Hz, 8bits, with zero level at value 80h.
  12.  
  13. 2-Compression -
  14.    A - The signal is converted to 4 bits, first subtracting DC value (80h) and
  15.        using a log (base 2) conversion of the absolute value:
  16.             in           out
  17.                 0  ->  0
  18.           0.   .1  ->  1
  19.           2.   .3  ->  2
  20.           4.   .7  ->  3
  21.           8.  .15  ->  4
  22.          16.  .31  ->  5
  23.          32.  .63  ->  6
  24.          64. .127  ->  7
  25.        Now the signal is 4 bits with zero level at 0 (-16 to 15).
  26.  
  27.    B - The samples are packed 2 samples per byte, high nibble corresponding
  28.        to first sample and the low nibble to next one
  29.  
  30.         EX:
  31.         t = 0  0000hhhh  <-- 4 bit sample
  32.             1  0000LLLL
  33.  
  34.                 pack  ->  hhhhLLLL
  35.  
  36.    C - Run lenght encoded, using FFh as flag character.
  37.  
  38.        EX:
  39.        00 32 84 84 84 84 84 84 34 35 FF 54 54 FE FE FE FE FE FE
  40.  
  41.        is converted to:
  42.        00 32 FF 05 84 34 35 FF 01 FF 54 54 FF 06 FE
  43.  
  44. 3-Coding - The signal is coded using 7 bits, from 30h to AFh.
  45.  
  46.         EX:
  47.         0 - AAAAaaaa      - >   0 - 0AAAAaaa   +  30h
  48.         1 - BBBBbbbb            1 - 0BBBBbbb   +  30h
  49.         2 - CCCCcccc            2 - 0CCCCccc   +  30h
  50.         3 - DDDDdddd            3 - 0DDDDddd   +  30h
  51.         4 - EEEEeeee            4 - 0EEEEeee   +  30h
  52.         5 - FFFFffff            5 - 0FFFFfff   +  30h
  53.         6 - GGGGgggg            6 - 0GGGGggg   +  30h
  54.                                 7 - 0abcdefg   +  30h
  55.  
  56. 4-Saving - The result is appended to the end of message at 64 bytes per line,
  57.   with a header:
  58.  
  59.    "[TALK]"  - 6 bytes - Identify a talkline
  60.    1Bh,"[8m" - 4 bytes - ANSI command to disable output, to avoid trash on
  61.                mail readers/terminal emulators without sound capabilities.
  62.    "A"       - 1 byte  -  This version.   Letters A to H are reserved.
  63.    "00000"   - 5 bytes -  The size of the sound in bytes, after coding and
  64.                           without line feeds (E3h).
  65.    E3h       - 1 byte  -  The character used as LF by the QWK file format.
  66.  
  67.    .. follow first 64 bytes,E3h,  and so on...
  68.  
  69. =========================================================================
  70.  
  71.    As example, the routines, used  to compress and expand the voice signal.
  72.  
  73. //-----------------------------------------------------------------------
  74. UINT WaveCompress (LPSTR Pk, LPSTR Wav, UINT nS)
  75. //
  76. //      Wav - intput signal
  77. //      Pk  - output signal
  78. //      nS  - number of data points
  79. //
  80. {
  81.   register UINT k, T;
  82.   char M;
  83.   UINT Ncomp, nS;
  84.  
  85.   Log2(Wav, nS);                        ;4 bit convert
  86.   Ncomp = nS >> 1;
  87. //                                      pack data
  88.   _asm  {
  89.             LES   SI,Wav        ;ES:SI -> Wav
  90.             MOV   DI,SI
  91.             MOV   CX,Ncomp
  92.             JCXZ  DONE
  93.      L1:    MOV   AX,ES:[SI]
  94.             SHL   AL,4          ;shift to HI nibble
  95.             AND   AX,0FF0h      ;mask
  96.             OR    AL,AH         ;merge
  97.             STOSB               ;save
  98.             ADD   SI,2
  99.             LOOP  L1
  100.      DONE:
  101.          }
  102. //
  103.   nS = 0;
  104.   Wav[Ncomp] = (char)(Wav[Ncomp-1]+1);  //make last different
  105.   for(k=0; k<Ncomp; k++)                //run lenght encode
  106.   {  T = 1;
  107.      M = Wav[k];
  108.      while (M == Wav[k+T])              //iqual next?
  109.      { if(T == 253) break;
  110.        else T = T + 1;                  //yes, bump T
  111.      }
  112.      if(T > 2 || M == '\xFF')
  113.      { Wav[nS++] = 0xFF;                //mark
  114.        Wav[nS++] =(char)T;              //total
  115.        k = k + T - 1;                   //next
  116.      }
  117.      Wav[nS++] = M;                     //save data
  118.   }
  119.   Ncomp = Pack(Pk, Wav, nS);            //7 bits convert
  120.   return Ncomp;
  121. }
  122. //-----------------------------------------------------------------
  123. LONG WaveExpand (LPSTR Wav, LPSTR Pk, UINT nS)
  124. //
  125. //      Pk  - input signal
  126. //      Wav - output signal
  127. //      nS  - number of data points
  128. //
  129. {
  130.   register UINT T, k;
  131.   UINT Cnt;
  132.   LONG nExp, Pt;
  133.  
  134. //
  135.    nSamp = Unpack(Pk, Pk, nSamp);             // 8 bits convert
  136.    nExp = 0;                                  // run lenght decode
  137.    for(Pt=0; (UINT)Pt < nSamp; Pt++)
  138.    {  if(Pk[Pt] == (char) 0xFF )
  139.       { Cnt = (BYTE) Pk[++Pt];
  140.         T = (char)Pk[++Pt];
  141.         for(k = 0; k < Cnt; k++) Wav[nExp++] = (char)T;
  142.       }
  143.       else
  144.       { Wav[nExp++] = Pk[Pt]; }
  145.    }
  146.    Cnt =(UINT)nExp;                           //unpack
  147.    _asm {
  148.             LES   DI, Wav
  149.             MOV   BX,Cnt
  150.             OR    BX,BX
  151.             JZ    DONE
  152.             MOV   SI,DI
  153.             ADD   SI,BX         ;end of data
  154.             ADD   BX,BX         ;end of unpacked data
  155.      L1:    MOV   AL,ES:[SI]
  156.             MOV   AH,AL         ;copy
  157.             SHR   AL,4          ;do inverse operation
  158.             AND   AX,0F0Fh     ;mask
  159.             MOV   ES:[DI+BX],AX ;save
  160.             DEC   SI
  161.             SUB   BX,2
  162.             JAE   L1            ;for all data points
  163.      DONE:
  164.         }
  165. //
  166.    nExp = nExp + nExp;
  167.    Exp2(Wave, nExp);                            ;8 bit convert
  168.    return nExp;
  169. }
  170. //=======================================================================
  171.  
  172.         Assebly routines to convert to and from 7 bits.
  173.  
  174. ;-------------------------------------------------------------------------
  175. ;       UINT = Pack (LPSTR, LPSTR, UINT);
  176. ;
  177. _Pack   PROC    FAR
  178.         PUSH    BP
  179.         MOV     BP,SP
  180.         PUSHF
  181.         CLD                     ;up
  182.         PUSH    DS
  183.         PUSH    SI
  184.         PUSH    DI
  185.         XOR     AX,AX           ;zero return value
  186.         MOV     CX,[BP+14]      ;size  (up to 64k)
  187.         JCXZ    PACK9
  188.         LES     DI,[BP+6];
  189.         LDS     SI,[BP+10];     ;DS:SI -> string
  190.         XOR     BX,BX           ;byte count
  191.         ADD     CX,SI           ;offset end of input string
  192.         PUSH    DI              ;save it
  193. ;
  194. PACK1:  MOV     DX,BX           ;insert a 0E3h each 64 bytes
  195.         AND     DX,3FH          ;test
  196.         JNZ     @F
  197.         MOV     AL,0E3h         ;LF (on QWK...)
  198.         STOSB                   ;insert
  199. @@:     CMP     SI,CX           ;end of processing?
  200.         JAE     PACK2           
  201.         LODSW                   ;-- 1 & 2
  202.         SHR     AL,1            ;-> 7, bit 0 to CY
  203.         RCL     DH,1            ;CY to bit 0 on DH
  204.         SHR     AH,1            ;repeat to next byte
  205.         RCL     DH,1
  206.         ADD     AX,3030h        ;translate to 30-A0h
  207.         STOSW                   ;ok, save it
  208.         LODSW
  209.         SHR     AL,1            ;repeat for bytes 3 & 4
  210.         RCL     DH,1
  211.         SHR     AH,1
  212.         RCL     DH,1
  213.         ADD     AX,3030h
  214.         STOSW
  215.         LODSW
  216.         SHR     AL,1            ;and 5 & 6
  217.         RCL     DH,1
  218.         SHR     AH,1
  219.         RCL     DH,1
  220.         ADD     AX,3030h
  221.         STOSW
  222.         LODSB
  223.         SHR     AL,1            ;the last one...
  224.         RCL     DH,1            ;
  225.         MOV     AH,DH           ;save DH (7 saved bits)
  226.         ADD     AX,3030h        ;
  227.         STOSW                   ;
  228.         ADD     BX,8            ;total
  229.         JMP     PACK1
  230. PACK2:  MOV     AX,DI           ;new position
  231.         POP     DI              ;initial position
  232.         SUB     AX,DI           ;return total processed bytes
  233. PACK9:  XOR     DX,DX           ;AX:DX
  234.         POP     DI
  235.         POP     SI
  236.         POP     DS
  237.         POPF
  238.         MOV     SP,BP
  239.         POP     BP
  240.         RET
  241. _Pack   ENDP
  242. ;-------------------------------------------------------------
  243. ;       UINT = Unpack (LPSTR, LPSTR, UINT);
  244. ;
  245. _Unpack PROC    FAR
  246.         PUSH    BP
  247.         MOV     BP,SP
  248.         PUSHF
  249.         PUSH    DS
  250.         PUSH    SI
  251.         PUSH    DI
  252.         CLD                     ;up
  253.         XOR     AX,AX
  254.         MOV     CX,[BP+14]      ;size
  255.         JCXZ    UNPCK9
  256.         LES     DI,[BP+6];      ;ES:DI -> string
  257.         LDS     SI,[BP+10];     ;DS:SI -> string
  258.         PUSH    DI
  259. ;
  260. ;UNPCK0: LODSB
  261. ;        CMP     AL,30H          ;if out of range (30h -> AFh)
  262. ;        JB      @F              ;do not copy
  263. ;        CMP     AL,0B0H
  264. ;        JA      @F
  265. ;        STOSB
  266. ;@@:     LOOP    UNPCK0
  267. ;
  268. UNPCK0: LODSB                    ;-- pcbord/qmail file corruption fix
  269.         CMP     AL,30H
  270.         JAE     @F
  271.         CMP     AL,'#'           ;<<<
  272.         JNE     UNPK2
  273.         MOV     AL,'@'           ;<<<
  274. @@:     CMP     AL,0B0H
  275.         JA      UNPK2
  276.         STOSB
  277. UNPK2:  LOOP    UNPCK0
  278. ;                                ;------------
  279.         MOV     AX,DI
  280.         POP     DI
  281.         SUB     AX,DI           ;total "clean" bytes
  282.         LDS     SI,[BP+6]
  283.         LES     DI,[BP+6]       ;works only on destination
  284.         ADD     AX,7
  285.         SHR     AX,3            ;number of loops
  286.         MOV     CX,AX
  287.         MOV     BX,7
  288.         MUL     BX              ;number of bytes
  289.         MOV     BX,AX           ;save on BX
  290. UNPCK1: MOV     DH,[SI+7]       ;get saved bit
  291.         SUB     DH,30h          ;convert to 0 - 7Fh
  292.         RCL     DH,1
  293.         LODSW
  294.         SUB     AX,3030h        ;convert data too
  295.         RCL     DH,1            ;bit -> CY
  296.         RCL     AL,1            ;insert on byte
  297.         RCL     DH,1            ;next byte
  298.         RCL     AH,1
  299.         STOSW                   ;save
  300.         LODSW
  301.         SUB     AX,3030h        ;next 2 bytes
  302.         RCL     DH,1
  303.         RCL     AL,1
  304.         RCL     DH,1
  305.         RCL     AH,1
  306.         STOSW
  307.         LODSW
  308.         SUB     AX,3030h        ;bytes 5 & 6
  309.         RCL     DH,1
  310.         RCL     AL,1
  311.         RCL     DH,1
  312.         RCL     AH,1
  313.         STOSW
  314.         LODSW
  315.         SUB     AL,30h          ;the last...
  316.         RCL     DH,1
  317.         RCL     AL,1
  318.         STOSB
  319.         LOOP    UNPCK1          ;repeat all
  320.         MOV     AX,BX
  321. UNPCK9: XOR     DX,DX           ;return total processed.
  322.         POP     DI
  323.         POP     SI
  324.         POP     DS
  325.         POPF
  326.         MOV     SP,BP
  327.         POP     BP
  328.         RET
  329. _Unpack ENDP
  330. ;---------------------------------------------------------------------
  331. ;       Assembly routines to convert from 8 to 4 bits and from 4 to 8
  332. ;---------------------------------------------------------------------
  333. ;       Log2 (LPSTR, UINT);
  334. ;
  335. _Log2   PROC    FAR
  336.         PUSH    BP
  337.         MOV     BP,SP
  338.         PUSHF
  339.         PUSH    ES
  340.         PUSH    DI
  341.         CLD
  342.         MOV     BX,[BP+10]      ;size to CX
  343.         OR      BX,BX
  344.         JZ      LOGC9
  345.         LES     DI,[BP+6];      ;ES:DI -> in/out - in place conversion
  346. LOGC1:  MOV     AL,ES:[DI]
  347.         XOR     CH,CH           ;zero
  348.         MOV     DL,CH           ;
  349.         sub     al,80h          ;remove DC value (-128..127)
  350.         OR      AL,AL
  351.         JNS     @F              ;if positive, go
  352.         NEG     AL              ;signal change
  353.         MOV     DL,8            ;signal bit
  354. @@:     AND     AL,7FH
  355.         SHL     AL,1
  356.         MOV     CL,7
  357. @@:     SHL     AL,1
  358.         JC      @F
  359.         LOOP    @B
  360. @@:     OR      CL,DL           ;insert signal
  361.         MOV     AL,CL
  362. ;
  363.         STOSB                   ;save
  364.         DEC     BX              ;end test
  365.         JNZ     LOGC1           ;no, more...
  366. LOGC9:  POP     DI
  367.         POP     ES
  368.         POPF
  369.         MOV     SP,BP
  370.         POP     BP
  371.         RET
  372. _Log2   ENDP
  373. ;-------------------------------------------------------------------
  374. ;       Exp2 (LPSTR, UINT);
  375. ;
  376. _LogExp PROC    FAR
  377.         PUSH    BP
  378.         MOV     BP,SP
  379.         PUSHF
  380.         PUSH    ES
  381.         PUSH    DI
  382.         CLD                     ;up
  383.         XOR     AX,AX
  384.         MOV     BX,[BP+10]      ;size
  385.         OR      BX,BX
  386.         JZ      LOGE9
  387.         LES     DI,[BP+6];      ;ES:DI -> in/out
  388.         XOR     CH,CH
  389. LOGE1:  MOV     AL,ES:[DI]
  390.         XOR     AH,AH
  391. ;
  392.         MOV     CL,AL           ;copy
  393.         AND     CL,7            ;signal mask
  394.         STC
  395.         RCL     AH,CL           ;exp
  396.         TEST    AL,8
  397.         JZ      @F              ;if positive
  398.         NEG     AH
  399. @@:     ADD     AH,80H          ;recover offset
  400.         MOV     AL,AH
  401.         STOSB                   ;save
  402.         DEC     BX
  403.         JNZ     LOGE1           ;loop
  404. LOGE9:  POP     DI
  405.         POP     ES
  406.         POPF
  407.         MOV     SP,BP
  408.         POP     BP
  409.         RET
  410. _Exp2   ENDP
  411. ;========================================================================
  412.  
  413. OBS: The music appended to the end of messages is a .MID file only coded
  414. into 7 bits.     The file header is the same, only the identifier "TALK"
  415. change to "MIDI".
  416.  
  417. ==========================================================================
  418.                                             Carlos Pires, Rio, March 1993.
  419. ==========================================================================
  420. NOTE: Unpack routine correction to avoid file corruption over some BBSs
  421.       systems, the change of "@" by "#".
  422.                                                                 June, 1993.
  423. ==========================================================================
  424.  
  425.